package com.zshan.clinic.admin.service.clinic;

import cn.hutool.system.UserInfo;
import com.zshan.clinic.admin.constant.Constants;
import com.zshan.clinic.admin.entity.dto.ClinicEmpDTO;
import com.zshan.clinic.admin.entity.dto.ClinicInfoDTO;
import com.zshan.clinic.admin.entity.vo.ClinicInfoVo;
import com.zshan.clinic.admin.entity.vo.ClinicInfoWebVo;
import com.zshan.clinic.admin.mapper.clinic.SpecClinicInfoMapper;
import com.zshan.clinic.common.constant.CommonConstant;
import com.zshan.clinic.common.enums.OperateTypeEnum;
import com.zshan.clinic.common.enums.ReqSourceEnum;
import com.zshan.clinic.common.enums.YesOrNoEnum;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.crypto.CryptoUtils;
import com.zshan.clinic.common.util.date.DateTimeUtils;
import com.zshan.clinic.common.util.page.PageInfo;
import com.zshan.clinic.common.util.page.PageUtils;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.common.util.token.JWTHS256;
import com.zshan.clinic.database.dao.ClinicInfoMapper;
import com.zshan.clinic.database.model.ClinicEmp;
import com.zshan.clinic.database.model.ClinicInfo;
import com.zshan.clinic.database.model.ClinicInfoExample;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 诊所信息
 */
@Service
@Slf4j
public class ClinicInfoService {

    @Autowired
    private ClinicInfoMapper clinicInfoMapper;

    @Autowired
    private SpecClinicInfoMapper specClinicInfoMapper;

    @Autowired
    private ClinicEmpService clinicEmpService;


    /**
     * 获取诊所信息
     * @param clinicId
     * @return
     */
    public ClinicInfoWebVo getClinicInfoForWeb(Long clinicId){
        ClinicInfo clinicInfo = getClinicById(clinicId);
        if(clinicInfo == null){
            throw new BusinessFailException("诊所不存在");
        }
        ClinicInfoWebVo clinicInfoWebVo = new ClinicInfoWebVo();
        BeanUtils.copyProperties(clinicInfo,clinicInfoWebVo);
        return clinicInfoWebVo;
    }

    /**
     * 获取诊所信息
     * @param clinicId
     * @return
     */
    public ClinicInfo getClinicById(Long clinicId){
        ClinicInfo clinicInfo = getClinicInfoById(clinicId);
        if(clinicInfo == null){
            throw new BusinessFailException("诊所不存在");
        }
        if(YesOrNoEnum.NO.getValue().equals(clinicInfo.getIsEnabled())){
            throw new BusinessFailException("合作已终止");
        }
        Date date = new Date();
        if(DateTimeUtils.secondsBetween(date,clinicInfo.getStartTime()) > 0){
            throw new BusinessFailException("合作未开始");
        }
        if(DateTimeUtils.secondsBetween(date,clinicInfo.getEndTime()) < 0){
            throw new BusinessFailException("合作已结束");
        }
        return clinicInfo;
    }

    /**
     * 查询诊所列表
     * @param clinicId
     * @param clinicName
     * @param admin
     * @param phone
     * @param license
     * @param isEnabled
     * @param pageNo
     * @param pageSize
     * @return
     */
    public PageInfo<ClinicInfoVo> getClinicListByCondition(Long clinicId, String clinicName, String admin, String phone, String license, String isEnabled, Integer pageNo, Integer pageSize){
        Long totalCount = specClinicInfoMapper.getClinicCountByCondition(clinicId,clinicName,admin,phone,license,isEnabled);
        if(StringUtil.isBlank(totalCount)){
            return PageInfo.build();
        }
        List<ClinicInfoVo> clinicInfoVoList = specClinicInfoMapper.getClinicListByCondition(clinicId,clinicName,admin,phone,license,isEnabled, PageUtils.getOffset(pageNo,pageSize),pageSize);
        return new PageInfo<>(totalCount,clinicInfoVoList);
    }

    /**
     * 添加诊所
     * @param clinicInfo
     */
    @Transactional(rollbackFor = Exception.class)
    public void add(ClinicInfoDTO clinicInfo){
        validateClinic(clinicInfo, OperateTypeEnum.ADD.getValue(),ReqSourceEnum.ADMIN.getValue());
        clinicInfo.setIsEnabled(YesOrNoEnum.YES.getValue());
        clinicInfo.setIsDelete(YesOrNoEnum.NO.getValue());
        clinicInfo.setCreateTime(new Date());
        clinicInfoMapper.insertSelective(clinicInfo);
        //初始化诊所管理员账户
        ClinicEmpDTO clinicEmpDTO = new ClinicEmpDTO();
        clinicEmpDTO.setEmpName(clinicInfo.getAdmin());
        clinicEmpDTO.setPassword(CryptoUtils.md5(Constants.DEFAULT_PASS));
        clinicEmpDTO.setPhone(clinicInfo.getPhone());
        clinicEmpDTO.setIsAdmin(YesOrNoEnum.YES.getValue());
        clinicEmpDTO.setClinicId(clinicInfo.getClinicId());
        clinicEmpDTO.setCreateUserId(clinicInfo.getCreateUserId());
        clinicEmpDTO.setCreateBy(clinicInfo.getCreateBy());
        clinicEmpService.add(clinicEmpDTO);
   }

    /**
     * 修改
     * @param clinicInfoDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(ClinicInfoDTO clinicInfoDTO,String reqSource){
        validateClinic(clinicInfoDTO,OperateTypeEnum.EDIT.getValue(),reqSource);
        ClinicInfo dbClinicInfo = getClinicInfoById(clinicInfoDTO.getClinicId());
        if(dbClinicInfo == null){
            throw new BusinessFailException("诊所不存在");
        }
        clinicInfoDTO.setUpdateTime(new Date());
        clinicInfoMapper.updateByPrimaryKeySelective(clinicInfoDTO);
        //修改管理员信息
        if(ReqSourceEnum.ADMIN.getValue().equals(reqSource)){
            ClinicEmp clinicEmp = clinicEmpService.getClinicAdmin(clinicInfoDTO.getClinicId());
            if(clinicEmp == null){
                throw new BusinessFailException("没有找到管理员");
            }
            boolean isUpdate = false;
            if(!clinicInfoDTO.getAdmin().equals(clinicEmp.getEmpName())){
                isUpdate = true;
                clinicEmp.setEmpName(clinicInfoDTO.getAdmin());
            }
            if(!clinicInfoDTO.getPhone().equals(clinicEmp.getPhone())){
                isUpdate = true;
                clinicEmp.setPhone(clinicInfoDTO.getPhone());
            }
            if(!isUpdate){
                return;
            }
            clinicEmp.setUpdateUserId(clinicInfoDTO.getUpdateUserId());
            clinicEmp.setUpdateBy(clinicInfoDTO.getUpdateBy());
            ClinicEmpDTO clinicEmpDTO = new ClinicEmpDTO();
            BeanUtils.copyProperties(clinicEmp,clinicEmpDTO);
            clinicEmpService.update(clinicEmpDTO);
        }
    }

    /**
     * 启用
     * @param clinicInfo
     */
    @Transactional(rollbackFor = Exception.class)
    public void enable(ClinicInfo clinicInfo) {
        ClinicInfo dbClinicInfo = getClinicInfoById(clinicInfo.getClinicId());
        if(dbClinicInfo == null){
            throw new BusinessFailException("诊所不存在");
        }
        if(YesOrNoEnum.YES.getValue().equals(dbClinicInfo.getIsEnabled())){
            return;
        }
        dbClinicInfo.setIsEnabled(YesOrNoEnum.YES.getValue());
        dbClinicInfo.setUpdateUserId(clinicInfo.getUpdateUserId());
        dbClinicInfo.setUpdateBy(clinicInfo.getUpdateBy());
        dbClinicInfo.setUpdateTime(new Date());
        clinicInfoMapper.updateByPrimaryKeySelective(dbClinicInfo);
    }

    /**
     * 停用
     * @param clinicInfo
     */
    @Transactional(rollbackFor = Exception.class)
    public void disable(ClinicInfo clinicInfo) {
        ClinicInfo dbClinicInfo = getClinicInfoById(clinicInfo.getClinicId());
        if(dbClinicInfo == null){
            throw new BusinessFailException("诊所不存在");
        }
        if(YesOrNoEnum.NO.getValue().equals(dbClinicInfo.getIsEnabled())){
            return;
        }
        dbClinicInfo.setIsEnabled(YesOrNoEnum.NO.getValue());
        dbClinicInfo.setUpdateUserId(clinicInfo.getUpdateUserId());
        dbClinicInfo.setUpdateBy(clinicInfo.getUpdateBy());
        dbClinicInfo.setUpdateTime(new Date());
        clinicInfoMapper.updateByPrimaryKeySelective(dbClinicInfo);
    }


    /**
     * 获取诊所信息
     * @param clinicId
     * @return
     */
    public ClinicInfo getClinicInfoById(Long clinicId){
        if(clinicId == null || clinicId == 0L){
            return null;
        }
        ClinicInfo clinicInfo = clinicInfoMapper.selectByPrimaryKey(clinicId);
        if(clinicInfo == null || YesOrNoEnum.YES.getValue().equals(clinicInfo.getIsDelete())){
            return null;
        }
        return clinicInfo;
    }

    /**
     * 诊所数
     * @param license
     * @return
     */
    public Long getClinicCountByLicense(String license,Long clinicId){
        ClinicInfoExample example = new ClinicInfoExample();
        ClinicInfoExample.Criteria criteria = example.createCriteria();
        criteria.andLicenseEqualTo(license);
        if(!StringUtil.isBlank(clinicId)){
            criteria.andClinicIdNotEqualTo(clinicId);
        }
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        return clinicInfoMapper.countByExample(example);
    }

    /**
     * 诊所信息验证
     * @param clinicInfo
     */
    public void validateClinic(ClinicInfoDTO clinicInfo,String operateType,String reqSource){
        if(StringUtil.isBlank(clinicInfo.getLogo())){
            clinicInfo.setLogo(Constants.DEFAULT_LOGO);
        }
        if(StringUtil.hasBlank(clinicInfo.getProvince(),clinicInfo.getCity(),clinicInfo.getCounty())){
            throw new BusinessFailException("请选择诊所所在的区域");
        }
        if(StringUtil.isBlank(clinicInfo.getAddress())){
            throw new BusinessFailException("请填写诊所具体地址");
        }
        if(ReqSourceEnum.ADMIN.getValue().equals(reqSource)){
            //从后台发起的请求
            clinicInfo.setClinicName(StringUtil.removeAllWhitespace(clinicInfo.getClinicName()));
            if(StringUtil.isBlank(clinicInfo.getClinicName())){
                throw new BusinessFailException("诊所名不能为空");
            }
            if(StringUtil.isBlank(clinicInfo.getLicenseUrl())){
                throw new BusinessFailException("请上传营业执照");
            }
            if(clinicInfo.getStartTime() == null){
                throw new BusinessFailException("请选择合作的开始时间");
            }
            if(clinicInfo.getEndTime() == null){
                throw new BusinessFailException("请选择合作的结束时间");
            }
            if(StringUtil.isBlank(clinicInfo.getLicense())){
                throw new BusinessFailException("营业执照号不能为空");
            }
            Long clinicCount = getClinicCountByLicense(clinicInfo.getLicense(),clinicInfo.getClinicId());
            if(clinicCount > CommonConstant.DEFAULT_0){
                throw new BusinessFailException("营业执照已存在");
            }
            if(DateTimeUtils.secondsBetween(clinicInfo.getStartTime(),clinicInfo.getEndTime()) < 0){
                throw new BusinessFailException("开始时间不能晚于结束时间");
            }
            if(OperateTypeEnum.ADD.getValue().equals(operateType)){
//                if(StringUtil.isBlank(clinicInfo.getPassword())){
//                    throw new BusinessFailException("请填写密码");
//                }
//                if(StringUtil.isBlank(clinicInfo.getConfirmPwd())){
//                    throw new BusinessFailException("请填写确认密码");
//                }
//                if(!clinicInfo.getPassword().equals(clinicInfo.getConfirmPwd())){
//                    throw new BusinessFailException("两次密码输入不一致");
//                }
            }
        }
    }

}
